#include "stdafx.h"
#include "GdiHook.h"
#include "HookFunctions.h"
#include "HookDll.h"
#include "..\Common\Common.h"
#include "DataDef.h"

extern bool g_bHooked;
extern int g_StackDepth;
extern CCriticalSection SyncObj;
extern CMapEx<LPVOID,LPVOID,MEM_INFO,MEM_INFO> m_MemMap;
extern CArrayEx<HOOKFUNCDESC,HOOKFUNCDESC&> g_arrHookedFunctions;


//////////////////////////////////////////////////////////////////////////
//GDI allocation
//bitmap 
static LoadBitmapADef pOrgLoadBitmapA;
static LoadBitmapWDef pOrgLoadBitmapW;
static LoadImageADef pOrgLoadImageA;
static LoadImageWDef pOrgLoadImageW;
static CreateBitmapDef pOrgCreateBitmap;
static CreateBitmapIndirectDef pOrgCreateBitmapIndirect;
static CreateCompatibleBitmapDef pOrgCreateCompatibleBitmap;
static CreateDIBitmapDef pOrgCreateDIBitmap;
static CreateDIBSectionDef pOrgCreateDIBSection;
static CreateDiscardableBitmapDef pOrgCreateDiscardableBitmap;
static CopyImageDef pOrgCopyImage;
static GetIconInfoDef	 pOrgGetIconInfo;
static GetIconInfoExADef pOrgGetIconInfoExA;
static GetIconInfoExWDef pOrgGetIconInfoExW;
static DeleteObjectDef pOrgDeleteObject;

//////////////////////////////////////////////////////////////////////////
//icons
static CopyIconDef					pOrgCopyIcon;
static CreateIconDef				pOrgCreateIcon;
static CreateIconFromResourceDef	pOrgCreateIconFromResource;
static CreateIconFromResourceExDef	pOrgCreateIconFromResourceEx;
static CreateIconIndirectDef		pOrgCreateIconIndirect;
static DestroyIconDef				pOrgDestroyIcon;
static DuplicateIconDef				pOrgDuplicateIcon;
static ExtractAssociatedIconADef	pOrgExtractAssociatedIconA;
static ExtractAssociatedIconWDef	pOrgExtractAssociatedIconW;
static ExtractAssociatedIconExADef	pOrgExtractAssociatedIconExA;
static ExtractAssociatedIconExWDef	pOrgExtractAssociatedIconExW;
static ExtractIconADef				pOrgExtractIconA;
static ExtractIconWDef				pOrgExtractIconW;
static ExtractIconExADef			pOrgExtractIconExA;
static ExtractIconExWDef			pOrgExtractIconExW;
static LoadIconADef					pOrgLoadIconA;
static LoadIconWDef					pOrgLoadIconW;
static PrivateExtractIconsADef		pOrgPrivateExtractIconsA;
static PrivateExtractIconsWDef		pOrgPrivateExtractIconsW;


//////////////////////////////////////////////////////////////////////////
//cursor
static CreateCursorDef			pOrgCreateCursor;
static LoadCursorADef			pOrgLoadCursorA;
static LoadCursorWDef			pOrgLoadCursorW;
static LoadCursorFromFileADef	pOrgLoadCursorFromFileA;
static LoadCursorFromFileWDef	pOrgLoadCursorFromFileW;
static DestroyCursorDef			pOrgDestroyCursor;

//brush 
static CreateBrushIndirectDef pOrgCreateBrushIndirect;
static CreateSolidBrushDef pOrgCreateSolidBrush;
static CreatePatternBrushDef pOrgCreatePatternBrush;
static CreateDIBPatternBrushDef pOrgCreateDIBPatternBrush;
static CreateDIBPatternBrushPtDef pOrgCreateDIBPatternBrushPt;
static CreateHatchBrushDef pOrgCreateHatchBrush;

//device context 
static CreateCompatibleDCDef pOrgCreateCompatibleDC;
static CreateDCADef pOrgCreateDCA;
static CreateDCWDef pOrgCreateDCW;
static CreateICADef pOrgCreateICA;
static CreateICWDef pOrgCreateICW;
static GetDCDef pOrgGetDC;
static GetDCExDef pOrgGetDCEx;
static GetWindowDCDef pOrgGetWindowDC;
//static ReleaseDCDef pOrgReleaseDC;
static GdiReleaseDCDef pOrgGdiReleaseDC;
static DeleteDCDef pOrgDeleteDC;

//font 
static CreateFontADef pOrgCreateFontA;
static CreateFontWDef pOrgCreateFontW;
static CreateFontIndirectADef pOrgCreateFontIndirectA;
static CreateFontIndirectWDef pOrgCreateFontIndirectW;

//metafile 
static CreateMetaFileADef		pOrgCreateMetaFileA;
static CreateMetaFileWDef		pOrgCreateMetaFileW;
static CreateEnhMetaFileADef	pOrgCreateEnhMetaFileA;
static CreateEnhMetaFileWDef	pOrgCreateEnhMetaFileW;
static GetEnhMetaFileADef		pOrgGetEnhMetaFileA;
static GetEnhMetaFileWDef		pOrgGetEnhMetaFileW;
static GetMetaFileADef			pOrgGetMetaFileA;
static GetMetaFileWDef			pOrgGetMetaFileW;
static DeleteMetaFileDef		pOrgDeleteMetaFile;
static DeleteEnhMetaFileDef		pOrgDeleteEnhMetaFile;
static CopyEnhMetaFileADef		pOrgCopyEnhMetaFileA;
static CopyEnhMetaFileWDef		pOrgCopyEnhMetaFileW;
static CloseEnhMetaFileDef		pOrgCloseEnhMetaFile;
static CloseMetaFileDef			pOrgCloseMetaFile;

//region 
static PathToRegionDef pOrgPathToRegion;
static CreateEllipticRgnDef pOrgCreateEllipticRgn;
static CreateEllipticRgnIndirectDef pOrgCreateEllipticRgnIndirect;
static CreatePolygonRgnDef pOrgCreatePolygonRgn;
static CreatePolyPolygonRgnDef pOrgCreatePolyPolygonRgn;
static CreateRectRgnDef pOrgCreateRectRgn;
static CreateRectRgnIndirectDef pOrgCreateRectRgnIndirect;
static CreateRoundRectRgnDef pOrgCreateRoundRectRgn;
static ExtCreateRegionDef pOrgExtCreateRegion;
static DeleteRegionDef pOrgDeleteRegion;


//palette 
static CreateHalftonePaletteDef pOrgCreateHalftonePalette;
static CreatePaletteDef pOrgCreatePalette;

//////////////////////////////////////////////////////////////////////////
                 //gdi functions
//////////////////////////////////////////////////////////////////////////

// bitmap

//HANDLE WINAPI MyLoadImageA(HINSTANCE hInst,LPCSTR name,UINT type,int cx,int cy,UINT fuLoad)
//{
//    HANDLE hImg = pOrgLoadImageA(hInst,name,type,cx,cy,fuLoad);
//    CreateCallStack( hImg , 0 );
//    return hImg;
//}

//HANDLE WINAPI MyLoadImageW( HINSTANCE hInst,LPCWSTR name,UINT type,int cx,int cy,UINT fuLoad)
//{
//    HANDLE hImg = pOrgLoadImageW(hInst,name,type,cx,cy,fuLoad);
//    CreateCallStack( hImg , 0 );
//    return hImg;
//}



HBITMAP WINAPI MyCreateBitmap(  int nWidth,  int nHeight, UINT nPlanes,  UINT nBitCount,  CONST VOID *lpBits)
{
    HBITMAP hBmp =  pOrgCreateBitmap( nWidth,  nHeight, nPlanes,   nBitCount,  lpBits );
    CreateCallStack( hBmp , 0 );
    return hBmp;
}

HBITMAP WINAPI MyCreateBitmapIndirect(  CONST BITMAP *pbm )
{
    HBITMAP hBmp =  pOrgCreateBitmapIndirect( pbm );
    CreateCallStack( hBmp , 0 );
    return hBmp;
}

HBITMAP WINAPI MyCreateCompatibleBitmap(  HDC hdc,  int cx,  int cy)
{
    HBITMAP hBmp =  pOrgCreateCompatibleBitmap( hdc,   cx,   cy);
    CreateCallStack( hBmp , 0 );
    return hBmp;
}

HBITMAP WINAPI MyCreateDIBitmap(  HDC hdc,  CONST BITMAPINFOHEADER *pbmih,  DWORD flInit,  CONST VOID *pjBits,  CONST BITMAPINFO *pbmi,  UINT iUsage)
{
    HBITMAP hBmp =  pOrgCreateDIBitmap( hdc,   pbmih,   flInit,  pjBits,   pbmi,   iUsage);
    CreateCallStack( hBmp , 0 );
    return hBmp;
}

HBITMAP WINAPI MyCreateDIBSection( HDC hdc,  CONST BITMAPINFO *lpbmi,  UINT usage, VOID **ppvBits,  HANDLE hSection,  DWORD offset)
{
    HBITMAP hBmp =  pOrgCreateDIBSection( hdc,  lpbmi,  usage, ppvBits,  hSection,  offset );
    CreateCallStack( hBmp , 0 );
    return hBmp;
}


HBITMAP WINAPI MyCreateDiscardableBitmap( HDC hdc, int cx, int cy)
{
    HBITMAP hBmp =  pOrgCreateDiscardableBitmap( hdc, cx, cy );
    CreateCallStack( hBmp , 0 );
    return hBmp;
}

HANDLE  WINAPI MyCopyImage( HANDLE h, UINT type, int cx, int cy, UINT flags)
{
    HANDLE hBmp =  pOrgCopyImage(h, type, cx, cy, flags);
    int nType = 0;
    CreateCallStack( hBmp , type );
    return hBmp;
}

BOOL WINAPI MyGetIconInfo( HICON hIcon, PICONINFO piconinfo)
{
    BOOL bRet = pOrgGetIconInfo( hIcon, piconinfo );
    if( bRet )
    {
        CreateCallStack( piconinfo->hbmColor, 0 );

        if( piconinfo->hbmMask )
        {
            if( g_bHooked  )
            {
                MEM_INFO stInfo;
				CSingleLock lockObj( &SyncObj, TRUE );
                if( m_MemMap.Lookup( piconinfo->hbmColor, stInfo ))
                {
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[piconinfo->hbmMask] = stInfo2;
                }
            }
        }
        
    }
    return bRet;
}

BOOL WINAPI MyGetIconInfoExA( HICON hicon, PICONINFOEXA piconinfo)
{
    BOOL bRet = pOrgGetIconInfoExA( hicon, piconinfo );
    if( bRet )
    {
        CreateCallStack( piconinfo->hbmColor, 0 );
        if( piconinfo->hbmMask )
        {
            CSingleLock lockObj( &SyncObj, TRUE );
            if( g_bHooked  )
            {
                MEM_INFO stInfo;
                if( m_MemMap.Lookup( piconinfo->hbmColor, stInfo ))
                {
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                  
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[piconinfo->hbmMask] = stInfo2;
                }
            }
        }

    }
    return bRet;
}

BOOL WINAPI MyGetIconInfoExW( HICON hicon,PICONINFOEXW piconinfo)
{
    BOOL bRet = pOrgGetIconInfoExW( hicon, piconinfo );
    if( bRet )
    {
        CreateCallStack( piconinfo->hbmColor, 0 );
        if( piconinfo->hbmMask )
        {
            CSingleLock lockObj( &SyncObj, TRUE );
            if( g_bHooked )
            {
                MEM_INFO stInfo;
                if( m_MemMap.Lookup( piconinfo->hbmColor, stInfo ))
                {
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                  
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[piconinfo->hbmMask] = stInfo2;
                }
            }
        }
    }
    return bRet;
}


BOOL WINAPI MyDeleteObject(  HGDIOBJ ho)
{
    BOOL bRet =  pOrgDeleteObject( ho );
    if( bRet )
        RemoveCallStack( ho );
    return bRet;
}

//////////////////////////////////////////////////////////////////////////
//ICONS
HICON WINAPI MyCopyIcon( HICON hIcon)
{
    HICON hIconnew = pOrgCopyIcon( hIcon );
    CreateCallStack( hIconnew, IMAGE_ICON );
    return hIconnew;
}

HICON WINAPI MyCreateIcon(HINSTANCE hInstance,int nWidth,int nHeight,BYTE cPlanes,BYTE cBitsPixel,CONST BYTE *lpbANDbits,CONST BYTE *lpbXORbits)
{
    HICON hIcon = pOrgCreateIcon( hInstance,nWidth,nHeight,cPlanes,cBitsPixel,lpbANDbits,lpbXORbits) ;
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyCreateIconFromResource( PBYTE presbits, DWORD dwResSize, BOOL fIcon, DWORD dwVer)
{
    HICON hIcon = pOrgCreateIconFromResource(presbits, dwResSize, fIcon, dwVer);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyCreateIconFromResourceEx( PBYTE presbits, DWORD dwResSize,BOOL fIcon,DWORD dwVer,int cxDesired,int cyDesired,UINT Flags )
{
    HICON hIcon = pOrgCreateIconFromResourceEx(presbits, dwResSize,fIcon,dwVer,cxDesired,cyDesired,Flags );
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyCreateIconIndirect( PICONINFO piconinfo )
{
    HICON hIcon = pOrgCreateIconIndirect(piconinfo );
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

BOOL  WINAPI MyDestroyIcon(HICON hIcon)
{
    BOOL bRet = pOrgDestroyIcon( hIcon );
    if( bRet )
        RemoveCallStack( hIcon );
    return bRet;
}

HICON WINAPI MyDuplicateIcon(HINSTANCE hInst, HICON hIcon)
{
    HICON hIconnew = pOrgDuplicateIcon( hInst, hIcon );
    CreateCallStack( hIconnew, IMAGE_ICON );
    return hIconnew;
}

HICON WINAPI MyExtractAssociatedIconA(HINSTANCE hInst,  LPSTR lpIconPath,  LPWORD lpiIcon)
{
    HICON hIcon = pOrgExtractAssociatedIconA(hInst,  lpIconPath,  lpiIcon);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyExtractAssociatedIconW(HINSTANCE hInst,  LPWSTR lpIconPath,  LPWORD lpiIcon)
{
    HICON hIcon = pOrgExtractAssociatedIconW(hInst,  lpIconPath,  lpiIcon);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyExtractAssociatedIconExA(HINSTANCE hInst,LPSTR lpIconPath,  LPWORD lpiIconIndex,  LPWORD lpiIconId)
{
    HICON hIcon = pOrgExtractAssociatedIconExA(hInst,lpIconPath,  lpiIconIndex,  lpiIconId);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyExtractAssociatedIconExW(HINSTANCE hInst,LPWSTR lpIconPath,  LPWORD lpiIconIndex,  LPWORD lpiIconId)
{
    HICON hIcon = pOrgExtractAssociatedIconExW(hInst,lpIconPath,  lpiIconIndex,  lpiIconId);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyExtractIconA(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
{
    HICON hIcon = pOrgExtractIconA(hInst, lpszExeFileName, nIconIndex);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

HICON WINAPI MyExtractIconW(HINSTANCE hInst, LPCWSTR lpszExeFileName, UINT nIconIndex)
{
    HICON hIcon = pOrgExtractIconW(hInst, lpszExeFileName, nIconIndex);
    CreateCallStack( hIcon, IMAGE_ICON );
    return hIcon;
}

UINT  WINAPI MyExtractIconExA(LPCSTR lpszFile, int nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons)
{
    UINT uRet = pOrgExtractIconExA(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
    if( uRet <= 0 || ( -1 == nIconIndex && !phiconLarge && !phiconSmall))
    {
        return uRet;
    }
    MEM_INFO stInfo;	
    
    bool bFirst = true;
    if( g_bHooked )
    {	
        for( UINT uIdx = 1; uIdx < uRet; uIdx++ )
        {
            if( phiconLarge[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phiconLarge[uIdx], IMAGE_ICON );
					{
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phiconLarge[uIdx], stInfo ))
							bFirst = false;
					}
                }
                else
                {
                    CSingleLock lockObj( &SyncObj, TRUE );
					MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                 
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phiconLarge[uIdx]] = stInfo2;
                }					
            }

            if( phiconSmall[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phiconSmall[uIdx], IMAGE_ICON );

					{
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phiconLarge[uIdx], stInfo ))
							bFirst = false;
					}
                }
                else
                {
					CSingleLock lockObj( &SyncObj, TRUE );
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                  
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phiconSmall[uIdx]] = stInfo2;
                }					
            }
        }
    }		
    return uRet;
}

UINT  WINAPI MyExtractIconExW(LPCWSTR lpszFile, int nIconIndex,  HICON *phiconLarge, HICON *phiconSmall, UINT nIcons)
{
    UINT uRet = pOrgExtractIconExW(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
    if( uRet <= 0 || ( -1 == nIconIndex && !phiconLarge && !phiconSmall))
    {
        return uRet;
    }
    MEM_INFO stInfo;	
   
    bool bFirst = true;
    if( g_bHooked  )
    {
        for( UINT uIdx = 1; uIdx < uRet; uIdx++ )
        {
            if( phiconLarge[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phiconLarge[uIdx], IMAGE_ICON );
					{
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phiconLarge[0], stInfo ))
							bFirst = false;
					}
                }
                else
                {
					CSingleLock lockObj( &SyncObj, TRUE );
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                   
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phiconLarge[uIdx]] = stInfo2;
                }					
            }

            if( phiconSmall[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phiconSmall[uIdx], IMAGE_ICON );
					{ 
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phiconLarge[0], stInfo ))
							bFirst = false;
					}
                }
                else
                {
					CSingleLock lockObj( &SyncObj, TRUE );
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                   
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phiconSmall[uIdx]] = stInfo2;
                }					
            }
        }
    }		
    return uRet;
}

HICON WINAPI MyLoadIconA( HINSTANCE hInstance, LPCSTR lpIconName )
{
    HICON hIcon = pOrgLoadIconA(hInstance, lpIconName );
    if( hIcon && hInstance )
    {
        CreateCallStack( hIcon, IMAGE_ICON );
    }
    return hIcon;
}

HICON WINAPI MyLoadIconW( HINSTANCE hInstance, LPCWSTR lpIconName )
{
    HICON hIcon = pOrgLoadIconW(hInstance, lpIconName );
    if( hIcon && hInstance )
    {
        CreateCallStack( hIcon, IMAGE_ICON );
    }
    return hIcon;
}

UINT  WINAPI MyPrivateExtractIconsA( LPCSTR szFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid, UINT nIcons, UINT flags)
{
    UINT uRet = pOrgPrivateExtractIconsA(szFileName, nIconIndex, cxIcon, cyIcon, phicon, piconid, nIcons, flags);
    if( uRet <= 0 || !phicon )
    {
        return uRet;
    }
    MEM_INFO stInfo;	
   
    bool bFirst = true;
    if( g_bHooked  )
    {
        for( UINT uIdx = 1; uIdx < uRet; uIdx++ )
        {
            if( phicon[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phicon[uIdx], IMAGE_ICON );
					{
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phicon[uIdx], stInfo ))
							bFirst = false;
					}
                }
                else
                {
					CSingleLock lockObj( &SyncObj, TRUE );
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                  
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phicon[uIdx]] = stInfo2;
                }					
            }
        }
    }		
    return uRet;
}

UINT  WINAPI MyPrivateExtractIconsW( LPCWSTR szFileName, int nIconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT *piconid,UINT nIcons,UINT flags)
{
    UINT uRet = pOrgPrivateExtractIconsW(szFileName, nIconIndex, cxIcon, cyIcon, phicon, piconid, nIcons, flags);
    if( uRet <= 0 || !phicon )
    {
        return uRet;
    }
    MEM_INFO stInfo;	
    
    bool bFirst = true;
    if( g_bHooked )
    {
        for( UINT uIdx = 1; uIdx < uRet; uIdx++ )
        {
            if( phicon[uIdx] )
            {				
                if( bFirst )
                {
                    CreateCallStack( phicon[uIdx], IMAGE_ICON );

					{
						CSingleLock lockObj( &SyncObj, TRUE );
						if( m_MemMap.Lookup( phicon[uIdx], stInfo ))
							bFirst = false;
					}
                }
                else
                {
					CSingleLock lockObj( &SyncObj, TRUE );
                    MEM_INFO stInfo2;
                    stInfo2.nMemSize = stInfo.nMemSize;
                  
                    void * p = AllocMem(sizeof(STACK_ARRAY));
                    stInfo2.parCallStack = new( (void*)p ) STACK_ARRAY(g_StackDepth);
                    stInfo2.parCallStack->Copy( *stInfo.parCallStack );
                    m_MemMap[phicon[uIdx]] = stInfo2;
                }					
            }
        }
    }		
    return uRet;
}


//////////////////////////////////////////////////////////////////////////
// Cursors
HCURSOR WINAPI MyCreateCursor( HINSTANCE hInst, int xHotSpot, int yHotSpot,int nWidth, int nHeight, CONST VOID *pvANDPlane,CONST VOID *pvXORPlane)
{
    HCURSOR hCur = pOrgCreateCursor(hInst, xHotSpot, yHotSpot,nWidth, nHeight, pvANDPlane,pvXORPlane);
    CreateCallStack( hCur, IMAGE_CURSOR);
    return hCur;
}

HCURSOR WINAPI MyLoadCursorA( HINSTANCE hInstance, LPCSTR lpCursorName)
{
    HCURSOR hCur = pOrgLoadCursorA( hInstance, lpCursorName );
    if( hInstance )
    {
        CreateCallStack( hCur, IMAGE_CURSOR );
    }	
    return hCur;
}

HCURSOR WINAPI MyLoadCursorW( HINSTANCE hInstance, LPCWSTR lpCursorName)
{
    HCURSOR hCur = pOrgLoadCursorW( hInstance, lpCursorName );
    if( hInstance )
    {
        CreateCallStack( hCur, IMAGE_CURSOR );
    }	
    return hCur;
}

HCURSOR WINAPI MyLoadCursorFromFileA( LPCSTR lpFileName )
{
    HCURSOR hCur = pOrgLoadCursorFromFileA(lpFileName);
    CreateCallStack( hCur,IMAGE_CURSOR );
    return hCur;
}

HCURSOR WINAPI MyLoadCursorFromFileW( LPCWSTR lpFileName )
{
    HCURSOR hCur = pOrgLoadCursorFromFileW(lpFileName);
    CreateCallStack( hCur, IMAGE_CURSOR );
    return hCur;
}

BOOL WINAPI MyDestroyCursor( HCURSOR hCursor )
{
    BOOL bRet = pOrgDestroyCursor( hCursor );
    if( bRet )
    {
        RemoveCallStack( hCursor );
    }
    return bRet;
}

//brush
HBRUSH  WINAPI MyCreateBrushIndirect(  CONST LOGBRUSH *plbrush)
{
    HBRUSH hBr = pOrgCreateBrushIndirect(plbrush);
    CreateCallStack( hBr, 0 );
    return hBr;
}

HBRUSH  WINAPI MyCreateSolidBrush(  COLORREF color)
{
    HBRUSH hBr = pOrgCreateSolidBrush(color);
    CreateCallStack( hBr, 0 );
    return hBr;
}

HBRUSH  WINAPI MyCreatePatternBrush(  HBITMAP hbm)
{
    HBRUSH hBr = pOrgCreatePatternBrush(hbm);
    CreateCallStack( hBr, 0 );
    return hBr;
}

HBRUSH  WINAPI MyCreateDIBPatternBrush(  HGLOBAL h,  UINT iUsage)
{
    HBRUSH hBr = pOrgCreateDIBPatternBrush(h, iUsage );
    CreateCallStack( hBr, 0 );
    return hBr;
}

HBRUSH  WINAPI MyCreateDIBPatternBrushPt(  CONST VOID *lpPackedDIB,  UINT iUsage)
{
    HBRUSH hBr = pOrgCreateDIBPatternBrushPt(lpPackedDIB,iUsage);
    CreateCallStack( hBr, 0 );
    return hBr;
}

HBRUSH  WINAPI MyCreateHatchBrush(  int iHatch,  COLORREF color)
{
    HBRUSH hBr = pOrgCreateHatchBrush( iHatch, color );
    CreateCallStack( hBr, 0 );
    return hBr;
}

// DC functions
 HDC WINAPI MyCreateCompatibleDC( HDC hdc )
 {
    HDC hDC = pOrgCreateCompatibleDC( hdc );
    CreateCallStack( hDC, 0 );
    return hDC;
 }
 
 HDC WINAPI MyCreateDCA( LPCSTR pwszDriver,  LPCSTR pwszDevice,  LPCSTR pszPort,  CONST DEVMODEA * pdm )
 {
    HDC hDC = pOrgCreateDCA( pwszDriver, pwszDevice, pszPort,  pdm );
    CreateCallStack( hDC , 0 );
    return hDC;
 }

 HDC WINAPI MyCreateDCW( LPCWSTR pwszDriver,  LPCWSTR pwszDevice,  LPCWSTR pszPort,  CONST DEVMODEW * pdm )
 {
    HDC hDC = pOrgCreateDCW( pwszDriver, pwszDevice, pszPort,  pdm );
    CreateCallStack( hDC, 0 );
    return hDC;
 }

 HDC WINAPI MyCreateICA( LPCSTR pszDriver,  LPCSTR pszDevice,  LPCSTR pszPort,  CONST DEVMODEA * pdm )
 {
    HDC hDC = pOrgCreateICA( pszDriver, pszDevice, pszPort,  pdm );
    CreateCallStack( hDC, 0 );
    return hDC;
 }

 HDC WINAPI MyCreateICW( LPCWSTR pszDriver,  LPCWSTR pszDevice,  LPCWSTR pszPort,  CONST DEVMODEW * pdm )
 {
    HDC hDC = pOrgCreateICW( pszDriver, pszDevice, pszPort,  pdm );
    CreateCallStack( hDC, 0 );
    return hDC;
 }

 HDC WINAPI MyGetDC( HWND hWnd )
 {
    HDC hDC = pOrgGetDC( hWnd );
    CreateCallStack( hDC, 0 );
    return hDC;
 }

 HDC WINAPI MyGetDCEx( HWND hWnd, HRGN hrgnClip, DWORD flags )
 {
    HDC hDC = pOrgGetDCEx(  hWnd, hrgnClip, flags );
    CreateCallStack( hDC, 0 );
    return hDC;
 }

 HDC WINAPI MyGetWindowDC( HWND hWnd )
 {
    HDC hDC = pOrgGetWindowDC( hWnd );
    CreateCallStack( hDC, 0 );
    return hDC;
 }


//int WINAPI MyReleaseDC( HWND hWnd, HDC hDC)
//{
//    int nRet = pOrgReleaseDC( hWnd, hDC );
//    if( nRet )
//        RemoveCallStack( hDC );
//    return nRet;
//}

int WINAPI MyGdiReleaseDC( HDC hDC)
{
    int nRet = pOrgGdiReleaseDC( hDC );
    if( nRet )
        RemoveCallStack( hDC );
    return nRet;
}


BOOL WINAPI MyDeleteDC( HDC hdc)
{
    BOOL bRet = pOrgDeleteDC( hdc );
    if( bRet )
    {
        RemoveCallStack( hdc );
    }	
    return bRet;
}

 // font functions
 HFONT WINAPI MyCreateFontA(  int cHeight,  int cWidth,  int cEscapement,  int cOrientation,  int cWeight,  DWORD bItalic,
     DWORD bUnderline,  DWORD bStrikeOut,  DWORD iCharSet,  DWORD iOutPrecision,  DWORD iClipPrecision,
     DWORD iQuality,  DWORD iPitchAndFamily, LPCSTR pszFaceName)
 {
    HFONT hFont = pOrgCreateFontA( cHeight,  cWidth,  cEscapement,  cOrientation,   cWeight,   bItalic,
          bUnderline,   bStrikeOut,   iCharSet,   iOutPrecision,   iClipPrecision,
          iQuality,   iPitchAndFamily,  pszFaceName );
    CreateCallStack( hFont, 0 );
    return hFont;
 }

 HFONT WINAPI MyCreateFontW(  int cHeight,  int cWidth,  int cEscapement,  int cOrientation,  int cWeight,  DWORD bItalic,
     DWORD bUnderline,  DWORD bStrikeOut,  DWORD iCharSet,  DWORD iOutPrecision,  DWORD iClipPrecision,
     DWORD iQuality,  DWORD iPitchAndFamily, LPCWSTR pszFaceName)
 {

     HFONT hFont = pOrgCreateFontW( cHeight,  cWidth,  cEscapement,  cOrientation,   cWeight,   bItalic,
         bUnderline,   bStrikeOut,   iCharSet,   iOutPrecision,   iClipPrecision,
         iQuality,   iPitchAndFamily,  pszFaceName );
     CreateCallStack( hFont, 0 );
     return hFont;
 }

 HFONT WINAPI MyCreateFontIndirectA(  CONST LOGFONTA *lplf)
 {
     HFONT hFont = pOrgCreateFontIndirectA( lplf );
     CreateCallStack( hFont, 0 );
     return hFont;
 }

 HFONT WINAPI MyCreateFontIndirectW( CONST LOGFONTW *lplf)
 {
     HFONT hFont = pOrgCreateFontIndirectW( lplf );
     CreateCallStack( hFont, 0 );
     return hFont;
 }

 // Meta File
HDC WINAPI MyCreateMetaFileA(  LPCSTR pszFile )
{
    HDC hDC = pOrgCreateMetaFileA( pszFile );
    CreateCallStack( hDC, 0 );
    return hDC;
}

HDC WINAPI MyCreateMetaFileW(  LPCWSTR pszFile )
{
    HDC hDC = pOrgCreateMetaFileW( pszFile );
    CreateCallStack( hDC, 0 );
    return hDC;
}

HDC WINAPI MyCreateEnhMetaFileA(  HDC hdc,  LPCSTR lpFilename,  CONST RECT *lprc,  LPCSTR lpDesc)
{
    HDC hDC = pOrgCreateEnhMetaFileA( hdc, lpFilename, lprc, lpDesc );
    CreateCallStack( hDC, 0 );
    return hDC;
}

HDC WINAPI MyCreateEnhMetaFileW(  HDC hdc,  LPCWSTR lpFilename,  CONST RECT *lprc,  LPCWSTR lpDesc)
{
    HDC hDC = pOrgCreateEnhMetaFileW( hdc, lpFilename, lprc, lpDesc );
    CreateCallStack( hDC, 0 );
    return hDC;

}
HENHMETAFILE WINAPI MyGetEnhMetaFileA(  LPCSTR lpName )
{
    HENHMETAFILE hMetaFile = pOrgGetEnhMetaFileA( lpName );
    CreateCallStack( hMetaFile, 0 );
    return hMetaFile;
}

HENHMETAFILE WINAPI MyGetEnhMetaFileW(  LPCWSTR lpName )
{
    HENHMETAFILE hMetaFile = pOrgGetEnhMetaFileW( lpName );
    CreateCallStack( hMetaFile, 0 );
    return hMetaFile;

}
HMETAFILE WINAPI MyGetMetaFileA(  LPCSTR lpName)
{
    HMETAFILE hMetaFile = pOrgGetMetaFileA( lpName );
    CreateCallStack( hMetaFile, 0 );
    return hMetaFile;
}

HMETAFILE WINAPI MyGetMetaFileW( LPCWSTR lpName )
{
    HMETAFILE hMetaFile = pOrgGetMetaFileW( lpName );
    CreateCallStack( hMetaFile, 0 );
    return hMetaFile ;

}
BOOL WINAPI MyDeleteMetaFile( HMETAFILE hmf )
{
    BOOL bRet = pOrgDeleteMetaFile( hmf );
    if( bRet )
    RemoveCallStack( hmf );
    return bRet;
}

BOOL WINAPI MyDeleteEnhMetaFile( HENHMETAFILE hmf )
{
    BOOL bRet = pOrgDeleteEnhMetaFile( hmf );
    if( bRet )
    {
        RemoveCallStack( hmf );
    }	
    return bRet;

}
HENHMETAFILE WINAPI MyCopyEnhMetaFileA( HENHMETAFILE hEnh, LPCSTR lpFileName)
{
    HENHMETAFILE hMetaFile = pOrgCopyEnhMetaFileA( hEnh, lpFileName );
    CreateCallStack( hMetaFile , 0 );
    return hMetaFile;
}

HENHMETAFILE WINAPI MyCopyEnhMetaFileW( HENHMETAFILE hEnh, LPCWSTR lpFileName)
{
    HENHMETAFILE hMetaFile = pOrgCopyEnhMetaFileW( hEnh, lpFileName );
    CreateCallStack( hMetaFile, 0 );
    return hMetaFile;
}

HENHMETAFILE WINAPI MyCloseEnhMetaFile( HDC hdc)
{
    HENHMETAFILE hMetaFile = pOrgCloseEnhMetaFile( hdc );
    if( hMetaFile )
    {
        RemoveCallStack( hdc );
        CreateCallStack( hMetaFile, 0 );
    }
    return hMetaFile;
}

HMETAFILE WINAPI MyCloseMetaFile( HDC hdc)
{
    HMETAFILE hMetaFile = pOrgCloseMetaFile( hdc );
    if( hMetaFile )
    {
        RemoveCallStack( hdc );
        CreateCallStack( hMetaFile, 0 );
    }	
    return hMetaFile;
}


// Pen
HPEN WINAPI MyCreatePen(  int iStyle,  int cWidth,  COLORREF color)
{
    HPEN hGDIObj = pOrgCreatePen( iStyle, cWidth, color );
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HPEN WINAPI MyCreatePenIndirect(  CONST LOGPEN *plpen)
{

    HPEN hGDIObj = pOrgCreatePenIndirect( plpen );
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HPEN WINAPI MyExtCreatePen( DWORD iPenStyle, DWORD cWidth, CONST LOGBRUSH *plbrush, DWORD cStyle, CONST DWORD *pstyle)
{
    HPEN hGDIObj = pOrgExtCreatePen( iPenStyle, cWidth, plbrush, cStyle, pstyle );
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}


// region 
HRGN WINAPI MyPathToRegion( HDC hdc)
{
    HRGN hGDIObj = pOrgPathToRegion(hdc);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreateEllipticRgn(  int x1,  int y1,  int x2, int y2)
{
    HRGN hGDIObj = pOrgCreateEllipticRgn( x1, y1, x2, y2 );
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreateEllipticRgnIndirect(  CONST RECT *lprect)
{
    HRGN hGDIObj = pOrgCreateEllipticRgnIndirect(lprect);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreatePolygonRgn( CONST POINT *pptl, int cPoint, int iMode)
{
    HRGN hGDIObj = pOrgCreatePolygonRgn(pptl,cPoint,iMode);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreatePolyPolygonRgn( CONST POINT *pptl, CONST INT  *pc, int cPoly, int iMode)
{
    HRGN hGDIObj = pOrgCreatePolyPolygonRgn(pptl,pc,cPoly,iMode);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreateRectRgn(  int x1,  int y1,  int x2,  int y2)
{
    HRGN hGDIObj = pOrgCreateRectRgn(x1,y1,x2,y2);
    CreateCallStack(hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreateRectRgnIndirect(  CONST RECT *lprect)
{
    HRGN hGDIObj = pOrgCreateRectRgnIndirect(lprect);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyCreateRoundRectRgn(  int x1,  int y1,  int x2,  int y2,  int w,  int h)
{
    HRGN hGDIObj = pOrgCreateRoundRectRgn(x1,y1,x2,y2,w,h);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HRGN WINAPI MyExtCreateRegion( CONST XFORM * lpx,  DWORD nCount, CONST RGNDATA * lpData)
{
    HRGN hGDIObj = pOrgExtCreateRegion(lpx,nCount,lpData);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

int WINAPI MyDeleteRegion(HRGN hrgn)
{
	int rt = pOrgDeleteRegion(hrgn);
	RemoveCallStack(hrgn);

	return rt;
}
 
//palette 
HPALETTE WINAPI MyCreateHalftonePalette(  HDC hdc)
{
    HPALETTE hGDIObj = pOrgCreateHalftonePalette(hdc);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}

HPALETTE WINAPI MyCreatePalette( CONST LOGPALETTE * plpal )
{
    HPALETTE hGDIObj = pOrgCreatePalette(plpal);
    CreateCallStack( hGDIObj, 0 );
    return hGDIObj;
}



CString GetGDIHandleType( HGDIOBJ hObj, SIZE_T nType )
{
	CString csType;
    if( nType == IMAGE_ICON ) 
    {
		HICON testIcon = 0;
		if(pOrgCopyIcon){
			testIcon = pOrgCopyIcon((HICON)hObj);
		}else{
			testIcon = CopyIcon((HICON)hObj);
		}

		if(0 == testIcon)
			return _T("Error");

		if(pOrgDestroyIcon){
			pOrgDestroyIcon((HICON)testIcon);
		}else{
			DestroyIcon((HICON)testIcon);
		}

		csType = _T("Icon");
        return csType;
    }
    else if( nType == IMAGE_CURSOR )
    {
		CURSORINFO cinfo;
		cinfo.cbSize  = sizeof (cinfo);
		if(!GetCursorInfo(&cinfo)){
			return _T("Error");
		}

        csType = _T("Cursor");
        return csType;
    }

	DWORD dwType = GetObjectType( hObj );
    switch( dwType )
    {
    case OBJ_BITMAP:
        csType = _T("Bitmap");
        break;
    case OBJ_BRUSH:
        csType = _T("Brush");
        break;
    case OBJ_COLORSPACE:
        csType = _T("Color space");
        break;
    case OBJ_DC:
        csType = _T( "Device context");
        break;
    case OBJ_ENHMETADC:
        csType = _T("Enhanced metafile DC");
        break;
    case OBJ_ENHMETAFILE:
        csType = _T("Enhanced metafile");
        break;
    case OBJ_EXTPEN:
        csType = _T("Extended pen");
        break;
    case OBJ_FONT:
        csType = _T("Font");
        break;
    case OBJ_MEMDC:
        csType = _T("Memory DC");
        break;
    case OBJ_METAFILE:
        csType = _T("Metafile");
        break;
    case OBJ_METADC:
        csType = _T("Metafile DC");
        break;
    case OBJ_PAL:
        csType = _T("Palette");
        break;
    case OBJ_PEN:
        csType = _T("Pen");
        break;
    case OBJ_REGION:
        csType = _T("Region");
        break;
	case 0 : //error ,get failed
		csType = _T("Error");
		break;
    default:
		csType.Format(_T("Unknown, type id: %d"),dwType) ;
        break;
    }
    return csType;

}

const int GDI_FUNC_NO = 83;
void HookGDIAlloc()
{
    HMODULE Gdi32 = LoadLibrary( "Gdi32.dll" );
    HMODULE User32 = LoadLibrary( "User32.dll" );
    HMODULE Shell32 = LoadLibrary( "Shell32.dll" );
    
    g_arrHookedFunctions.SetSize( GDI_FUNC_NO ); 
    int nIndex = 0;
    // Bitmap functions
    //REGISTER_HOOK(LoadBitmapA,User32 );
    //REGISTER_HOOK(LoadBitmapW,User32 );
    //REGISTER_HOOK(LoadImageA,User32 );
    //REGISTER_HOOK(LoadImageW,User32 );
    REGISTER_HOOK(CreateBitmap,Gdi32 );
    REGISTER_HOOK(CreateBitmapIndirect,Gdi32 );
    REGISTER_HOOK(CreateCompatibleBitmap,Gdi32 );
    REGISTER_HOOK(CreateDIBitmap,Gdi32 );
    REGISTER_HOOK(CreateDIBSection,Gdi32 );
    REGISTER_HOOK(CreateDiscardableBitmap,Gdi32 );
    REGISTER_HOOK(CopyImage,User32 );
    REGISTER_HOOK(GetIconInfo,User32 );
    //REGISTER_HOOK(GetIconInfoExA,User32 );
    REGISTER_HOOK(GetIconInfoExW,User32 );
    REGISTER_HOOK(DeleteObject,Gdi32 );
    
    //ICONS
    REGISTER_HOOK(CopyIcon,User32 );
    REGISTER_HOOK(CreateIcon,User32 );
    REGISTER_HOOK(CreateIconFromResource,User32 );
    REGISTER_HOOK(CreateIconFromResourceEx,User32 );
    REGISTER_HOOK(CreateIconIndirect,User32 );
    REGISTER_HOOK(DestroyIcon,User32 );
    REGISTER_HOOK(DuplicateIcon,Shell32 );
    REGISTER_HOOK(ExtractAssociatedIconA,Shell32 );
    REGISTER_HOOK(ExtractAssociatedIconW,Shell32 );
    REGISTER_HOOK(ExtractAssociatedIconExA,Shell32 );
    REGISTER_HOOK(ExtractAssociatedIconExW,Shell32 );
    REGISTER_HOOK(ExtractIconA,Shell32 );
    REGISTER_HOOK(ExtractIconW,Shell32 );
    REGISTER_HOOK(ExtractIconExA,Shell32 );
    REGISTER_HOOK(ExtractIconExW,Shell32 );
    REGISTER_HOOK(LoadIconA,User32 );
    REGISTER_HOOK(LoadIconW,User32 );
    REGISTER_HOOK(PrivateExtractIconsA,User32 );
    REGISTER_HOOK(PrivateExtractIconsW,User32 );

    // Cursor
    REGISTER_HOOK(CreateCursor,User32 );
    REGISTER_HOOK(LoadCursorA,User32 );
    REGISTER_HOOK(LoadCursorW,User32 );
    REGISTER_HOOK(LoadCursorFromFileA,User32 );
    REGISTER_HOOK(LoadCursorFromFileW,User32 );
    REGISTER_HOOK(DestroyCursor,User32 );


    // brush
    REGISTER_HOOK(CreateBrushIndirect,Gdi32 );
    REGISTER_HOOK(CreateSolidBrush,Gdi32 );
    REGISTER_HOOK(CreatePatternBrush,Gdi32 );
    REGISTER_HOOK(CreateDIBPatternBrush,Gdi32 );
    REGISTER_HOOK(CreateDIBPatternBrushPt,Gdi32 );
    REGISTER_HOOK(CreateHatchBrush,Gdi32 );

    // DC
    REGISTER_HOOK(CreateCompatibleDC,Gdi32 );
    REGISTER_HOOK(CreateDCA,Gdi32 );
    REGISTER_HOOK(CreateDCW,Gdi32 );
    REGISTER_HOOK(CreateICA,Gdi32 );
    REGISTER_HOOK(CreateICW,Gdi32 );
    REGISTER_HOOK(GetDC,User32 );
    REGISTER_HOOK(GetDCEx,User32 );
    REGISTER_HOOK(GetWindowDC,User32 );
    //REGISTER_HOOK(ReleaseDC,User32 );
	REGISTER_HOOK(GdiReleaseDC,Gdi32 );
	//GdiReleaseDCDef pGdiReleaseDC = (GdiReleaseDCDef)GetProcAddress(Dll, #Function); \
	//REGISTER_HOOK(GdiReleaseLocalDC,User32 );
    REGISTER_HOOK(DeleteDC,Gdi32 );
    

    // FONT
    REGISTER_HOOK(CreateFontA,Gdi32 );
    REGISTER_HOOK(CreateFontW,Gdi32 );
    REGISTER_HOOK(CreateFontIndirectA,Gdi32 );
    REGISTER_HOOK(CreateFontIndirectW,Gdi32 );

    // Metafile
    REGISTER_HOOK(CreateMetaFileA,Gdi32 );
    REGISTER_HOOK(CreateMetaFileW,Gdi32 );
    REGISTER_HOOK(CreateEnhMetaFileA,Gdi32 );
    REGISTER_HOOK(CreateEnhMetaFileW,Gdi32 );
    REGISTER_HOOK(GetEnhMetaFileA,Gdi32 );
    REGISTER_HOOK(GetEnhMetaFileW,Gdi32 );
    REGISTER_HOOK(GetMetaFileA,Gdi32 );
    REGISTER_HOOK(GetMetaFileW,Gdi32 );
    REGISTER_HOOK(DeleteMetaFile,Gdi32 );
    REGISTER_HOOK(DeleteEnhMetaFile,Gdi32 );
    REGISTER_HOOK(CopyEnhMetaFileA,Gdi32 );
    REGISTER_HOOK(CopyEnhMetaFileW,Gdi32 );
    REGISTER_HOOK(CloseEnhMetaFile,Gdi32 );
    REGISTER_HOOK(CloseMetaFile,Gdi32 );

    //Pen
    REGISTER_HOOK(CreatePen,Gdi32 );
    REGISTER_HOOK(CreatePenIndirect,Gdi32 );
    REGISTER_HOOK(ExtCreatePen,Gdi32 );

    //region
    REGISTER_HOOK(PathToRegion,Gdi32 );
    REGISTER_HOOK(CreateEllipticRgn,Gdi32 );
    REGISTER_HOOK(CreateEllipticRgnIndirect,Gdi32 );
    REGISTER_HOOK(CreatePolygonRgn,Gdi32 );
    REGISTER_HOOK(CreatePolyPolygonRgn,Gdi32 );
    REGISTER_HOOK(CreateRectRgn,Gdi32 );
    REGISTER_HOOK(CreateRectRgnIndirect,Gdi32 );
    REGISTER_HOOK(CreateRoundRectRgn,Gdi32 );
    REGISTER_HOOK(ExtCreateRegion,Gdi32 );
	//REGISTER_HOOK(DeleteRegion,Gdi32);

    //palette
    REGISTER_HOOK(CreateHalftonePalette,Gdi32 );
    REGISTER_HOOK(CreatePalette,Gdi32 );

    

    ASSERT( nIndex == GDI_FUNC_NO );
    HookDynamicLoadedFun( nIndex, g_arrHookedFunctions.GetData());

}